"""
数据验证器
用于验证爬取数据的格式和完整性
"""
import re
import logging
from typing import Dict, Any, Optional
from datetime import datetime

logger = logging.getLogger(__name__)


class DataValidator:
    """数据验证器"""
    
    @staticmethod
    def validate_list_item(data: Dict[str, Any]) -> tuple[bool, Optional[str]]:
        """
        验证列表项数据
        
        Returns:
            (is_valid, error_message)
        """
        required_fields = ['title', 'url']
        
        for field in required_fields:
            if field not in data or not data[field]:
                return False, f"Missing required field: {field}"
        
        # 验证URL格式
        if not DataValidator._is_valid_url(data['url']):
            return False, f"Invalid URL format: {data['url']}"
        
        # 验证发布时间格式（如果提供）
        if 'publish_time' in data and data['publish_time']:
            if not DataValidator._is_valid_datetime(data['publish_time']):
                return False, f"Invalid datetime format: {data['publish_time']}"
        
        return True, None
    
    @staticmethod
    def validate_detail_item(data: Dict[str, Any]) -> tuple[bool, Optional[str]]:
        """
        验证详情项数据
        
        Returns:
            (is_valid, error_message)
        """
        required_fields = ['project_number']
        
        for field in required_fields:
            if field not in data or not data[field]:
                return False, f"Missing required field: {field}"
        
        # 验证项目编号格式（基本检查）
        if len(data['project_number'].strip()) < 5:
            return False, f"Project number too short: {data['project_number']}"
        
        # 验证子详情页URL列表
        if 'sub_detail_urls' in data:
            if not isinstance(data['sub_detail_urls'], list):
                return False, "sub_detail_urls must be a list"
            
            for url in data['sub_detail_urls']:
                if not DataValidator._is_valid_url(url):
                    return False, f"Invalid sub detail URL: {url}"
        
        return True, None
    
    @staticmethod
    def validate_html_content(html: str) -> tuple[bool, Optional[str]]:
        """
        验证HTML内容
        
        Returns:
            (is_valid, error_message)
        """
        if not html or len(html.strip()) < 100:
            return False, "HTML content is too short or empty"
        
        # 检查是否包含基本的HTML标签
        if not re.search(r'<html|<body|<div', html, re.IGNORECASE):
            return False, "HTML content does not appear to be valid HTML"
        
        return True, None
    
    @staticmethod
    def _is_valid_url(url: str) -> bool:
        """验证URL格式"""
        url_pattern = re.compile(
            r'^https?://'  # http:// or https://
            r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|'  # domain...
            r'localhost|'  # localhost...
            r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'  # ...or ip
            r'(?::\d+)?'  # optional port
            r'(?:/?|[/?]\S+)$', re.IGNORECASE
        )
        return bool(url_pattern.match(url))
    
    @staticmethod
    def _is_valid_datetime(dt: Any) -> bool:
        """验证日期时间格式"""
        if isinstance(dt, datetime):
            return True
        
        if isinstance(dt, str):
            # 尝试解析常见的日期时间格式
            formats = [
                '%Y-%m-%d %H:%M:%S',
                '%Y-%m-%d',
                '%Y/%m/%d %H:%M:%S',
                '%Y/%m/%d',
            ]
            for fmt in formats:
                try:
                    datetime.strptime(dt, fmt)
                    return True
                except ValueError:
                    continue
        
        return False

